#include "mystdio.h"
// 打开文件！
FILE_* fopen_(const char* pathname,const char* mode)
{    int flags= 0;
    int defaultMode = 0666;

    // 比较打开方式！
    if(strcmp(mode,"r")==0)
    {
        flags |= O_RDONLY;
    }
    else if(strcmp(mode,"w")==0)
    {
        flags |= (O_WRONLY|O_CREAT|O_TRUNC);
    }
    else if(strcmp(mode,"a")==0)
    {
        flags |= (O_WRONLY|O_APPEND |O_CREAT);
    }
    else 
    {
        //todo
    }
    int fd = 0;
    // 正式打开文件！
    if(flags & O_RDONLY) fd = open(pathname,flags);
    else fd = open(pathname,flags,defaultMode);
    if(fd < 0)
    {
        const char* err = strerror(errno);
        write(2,err,strlen(err));
        return NULL;
    }
    // 创建结构体！
    FILE_* fp = (FILE_*)malloc(sizeof(FILE_));
    assert(fp);
    // 初始化结构体！
    fp->flags = SYNC_LINE;//默认设置为行刷新！ 
    fp->fileno = fd;
    fp -> cap =SIZE;
    fp->size = 0;
    //初始化缓冲区！
    memset(fp->buffer,0,SIZE);
    return fp;//这就是为什么打开一个就会返回一个fp指针！

}
//刷新
void fflush_(FILE_* fp)
{
    //要fflush首先就是要把数据写入操作系统里面！
    //因为我们的数据是在缓冲区里面的！
   if(fp->size >0) write(fp->fileno,fp->buffer,fp->size);
   fsync(fp->fileno);//强制要求操作系统进行外设刷新！
   //TODO 
}
// 关闭文件！
void fclose_(FILE_* fp)
{
    //关闭首先就要刷新缓冲区！
    fflush_(fp);
    close(fp->fileno);
} 
//对文件进行写
void fwrite_(const void* ptr,int num,FILE_*fp)
{
    //写入其实不是讲数据写入操作系统里面！
    //这是刷新干的事情！
    //写入其实是将数据写入缓冲区里面！
    memcpy(fp->buffer + fp->size, ptr, num);
    fp->size +=num;
    // 之所以加size是因为曾经还有放在缓冲区里面的但是没有被刷新出去的！
    //这里我们暂时不考虑缓冲区溢出的问题！

    //写入完毕要判断是否刷新！
    if(fp->flags & SYNC_NOW)
    {
        fflush_(fp);
        fp->size =0;//清空缓冲区！
    }
    else if(fp->flags & SYNC_LINE)
    {
        //如果有\n就把\n之前的所有数据都刷新！
        if(fp->buffer[fp->size-1] == '\n') // 这种方式比较粗暴！如果遇到aaaa\naaa就不好使了！遇到这种其实可以使用循环！
        {
            fflush_(fp);
            fp->size = 0;
        }

    }
    else if(fp->flags & SYNC_FULL)
    {
        if(fp->size == fp->cap)
        {
            fflush_(fp);
            fp->size =0;
        }
    }
    
}
